﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core;
using Cofe.Core.Implements;

namespace Cofe.Data
{
    [Export(typeof(ICofeService))]
    [ServicePriority(ServicePriorityAttribute.DefaultPriority_COFEDB)]
    public class EFDatabaseEntryConfig : IDatabaseConfigurator
    {
        public void OnDatabaseCreating(CofeDbContext context)
        {
            context.Database.ExecuteSqlCommand(
                "ALTER TABLE dbo.DatabaseEntry ADD CONSTRAINT UK_parseName UNIQUE (ParseName)");

            var dbEntry = new DatabaseEntry()
            {
                ParseName = "{" + EntryTypes.VolumeKey + "}",
                Label = EntryTypes.VolumeKey,
                SupportDefinitions = "",
                SupportedProperties = ""
            };
            dbEntry.Implementations.Add(new CofeDirectoryInfo(
                CofeServices.EntryConstructor.ConstructPropertyHost(
                CofeServices.EntryTypeInfoManager.GetRootPropertyProvider(EntryTypes.VolumeKey))));

            context.Entry(dbEntry).State = System.Data.EntityState.Added;
            context.SaveChanges();
        }

        public void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var databaseEntryConfig = modelBuilder.Entity<DatabaseEntry>();

            databaseEntryConfig.Property(e => e.ParseName).HasMaxLength(512).IsRequired();
            databaseEntryConfig.Property(e => e.Label).HasMaxLength(128).IsRequired();
            databaseEntryConfig.ToTable("DatabaseEntry");
            databaseEntryConfig.HasOptional(de => de.Parent)
                .WithMany(de => de.Children)
                .HasForeignKey(de => de.ParentId)
                .WillCascadeOnDelete(false);

            //databaseEntryConfig.HasMany(de => de.HashTags)
            //   .WithMany(t => t.AppliedEntries)
            //   .Map(mc =>
            //   {
            //       mc.ToTable("HashTag_Entries");
            //       mc.MapLeftKey("EntryId");
            //       mc.MapRightKey("TagId");
            //   });

            databaseEntryConfig
              .HasKey(de => de.Id)
              .HasMany(de => de.Implementations)
              .WithRequired(e => e.DatabaseEntry)
              .HasForeignKey(e => e.Id).WillCascadeOnDelete();

            databaseEntryConfig.HasOptional(de => de.EntryTypeInfo).WithMany().HasForeignKey(de => de.EntryTypeInfoId);
            databaseEntryConfig.HasOptional(de => de.LinkedEntry).WithMany().HasForeignKey(de => de.LinkedEntryId);

            databaseEntryConfig.Property(o => o.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            databaseEntryConfig.Property(de => de.Description).IsOptional();
            databaseEntryConfig.Property(de => de.SupportedProperties).HasMaxLength(2048).IsRequired();
            databaseEntryConfig.Property(de => de.SupportDefinitions).HasMaxLength(1024).IsRequired();
            databaseEntryConfig.Property(e => e.Position).IsOptional();


        }
    }
}
